<?php

/**
 * 
 * @desc This class defines Validator with set of rules
 * @author Barbushin Sergey http://www.linkedin.com/in/barbushin
 * 
 */
class Validator_Set {
	
	protected $rules = array();
	protected $errors = array();
	protected $multiErrorMode;
	protected $multiErrorModeImplode = "\n";

	public function __construct($multiErrorMode = false) {
		$this->multiErrorMode = $multiErrorMode;
	}

	public function add($valueName, $rules) {
		if (is_scalar($rules)) {
			$rules = array($rules);
		}
		$this->rules[$valueName] = $rules;
	}

	public function isValid($values, $valuesNames = null, $throwException = true) {
		
		if (!$valuesNames || $valuesNames === true) {
			$valuesNames = array_keys($this->rules);
		}
		elseif (is_scalar($valuesNames)) {
			$valuesNames = array_map('trim', explode(',', $valuesNames));
		}
		
		$this->errors = array();
		
		if (is_array($valuesNames)) {
			foreach ($valuesNames as $valueName) {
				if ($error = $this->getValueRulesError($valueName, isset($values[$valueName]) ? $values[$valueName] : null)) {
					$this->errors[$valueName] = $error;
				}
			}
		}
		
		if ($this->errors && $throwException) {
			throw new Validator_Exception($this->errors);
		}
		
		return !$this->errors;
	}

	protected function getValueRulesError($valueName, $value) {
		$error = null;
		
		if (isset($this->rules[$valueName])) {
			foreach ($this->rules[$valueName] as $rule) {
				if (!$rule->isValid($value)) {
					if ($this->multiErrorMode) {
						$error[] = $rule->getErrorText();
					}
					else {
						$error = $rule->getErrorText();
						break;
					}
				}
			}
		}
		if($error && $this->multiErrorMode && $this->multiErrorModeImplode) {
			return implode($this->multiErrorModeImplode, $error);
		}
		
		return $error;
	}

	public function getErrors() {
		return $this->errors;
	}
}
